package org.robert.export_client.easyexcel.read.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.robert.common.commonutil.exception.AppException;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.robert.export_client.aop.ExcelDictAdapter;
import org.robert.export_client.easyexcel.read.ExcelBaseSave;
import org.robert.export_client.easyexcel.read.entity.ExcelReadRequest;
import org.robert.export_client.easyexcel.read.listener.BaseDataListener;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Map;

/**
 * @Description
 * @Author robert
 * @Date 2024/1/13 22:39
 **/
@Slf4j
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@EqualsAndHashCode
public class ExcelReadAndSave<T> extends ExcelReadRequest<T> {

    private int batchCount = 1000; // 保存的数量

    private ExcelBaseSave<T> excelBaseSave;

    public ExcelReadAndSave(ExcelBaseSave<T> excelBaseSave,Class<T> clazz) {
        this.clazz = clazz;
        this.excelBaseSave = excelBaseSave;
    }

    public ExcelReadAndSave(Class<T> clazz,  ExcelBaseSave<T> excelBaseSave,
                            Map<String, Map<String, String>> dictMap) {
        this.clazz = clazz;
        this.excelBaseSave = excelBaseSave;
        this.dictMap = dictMap;
        if(MapUtils.isNotEmpty(dictMap)){
            this.checker = new ExcelDictAdapter<T>();
        }
    }

    public ExcelReadAndSave(Class<T> clazz,  ExcelBaseSave<T> excelBaseSave,
                            Map<String, Map<String, String>> dictMap, int batchCount) {
        this.clazz = clazz;
        this.excelBaseSave = excelBaseSave;
        this.dictMap = dictMap;
        this.batchCount = batchCount;
        if(MapUtils.isNotEmpty(dictMap)){
            this.checker = new ExcelDictAdapter<T>();
        }
    }

    public ExcelReadAndSave(ExcelBaseSave<T> excelBaseSave,Class<T> clazz, String path) {
        this.path = path;
        this.clazz = clazz;
        this.excelBaseSave = excelBaseSave;
    }

    public ExcelReadAndSave(Class<T> clazz,  ExcelBaseSave<T> excelBaseSave,String path,
                            Map<String, Map<String, String>> dictMap) {
        this.path = path;
        this.clazz = clazz;
        this.excelBaseSave = excelBaseSave;
        this.dictMap = dictMap;
        if(MapUtils.isNotEmpty(dictMap)){
            this.checker = new ExcelDictAdapter<T>();
        }
    }

    public ExcelReadAndSave(Class<T> clazz,  ExcelBaseSave<T> excelBaseSave, String path,
                            Map<String, Map<String, String>> dictMap, int batchCount) {
        this.path = path;
        this.clazz = clazz;
        this.excelBaseSave = excelBaseSave;
        this.dictMap = dictMap;
        this.batchCount = batchCount;
        if(MapUtils.isNotEmpty(dictMap)){
            this.checker = new ExcelDictAdapter<T>();
        }
    }

    public boolean check(){
        return !(excelBaseSave == null || clazz == null || batchCount == 0);
    }


    /**
     * web上传读取, 持指定顺序读取,执行title，时间格式转换
     * @throws IOException
     */
    public void read(MultipartFile file) throws IOException {
        if(!check()){
            throw new AppException("500", "参数异常");
        }
        EasyExcel.read(file.getInputStream(),
                clazz, new BaseDataListener(batchCount,
                                excelBaseSave,
                                dictMap))
                .sheet().doRead();
    }
    /**
     * 磁盘读取, 支持指定顺序读取
     * @throws IOException
     */
    public void read(){
        if(!check() || StringUtils.isBlank(path)){
            throw new AppException("500", "参数异常");
        }
        // 一个文件一个reader
        try (ExcelReader excelReader = EasyExcel.read(path, clazz,
                new BaseDataListener(batchCount, excelBaseSave,
                        dictMap)).build()) {
            // 构建一个sheet 这里可以指定名字或者no
            ReadSheet readSheet = EasyExcel.readSheet(0).build();
            // 读取一个sheet
            excelReader.read(readSheet);
        }

    }

}
